home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
dev
/
gcc
/
fd2inline.LHA
/
fd2inline
/
RCS
/
fd2inline.c,v
Wrap
Text File
|
1992-03-23
|
32KB
|
1,378 lines
head 1.2;
branch ;
access ;
symbols ;
locks baron:1.2; strict;
comment @ * @;
1.2
date 92.03.23.12.41.13; author baron; state Exp;
branches ;
next 1.1;
1.1
date 92.03.11.19.41.31; author baron; state Exp;
branches ;
next ;
desc
@Parse an fd file and output inline definitions and the like.
@
1.2
log
@First 0.9 distribution to Markus Wild only.
@
text
@/*
* fd2inline
*
* should be able to parse CBM fd files and generate vanilla inline calls
* for gcc. Works as a filter. This is a 0.9 evaluation version. Don't expect
* miracles (yet...).
*
* by Wolfgang Baron, all rights reserved.
*
*/
/* $Id: fd2inline.c,v 1.2 92/03/23 12:38:05 baron Exp Locker: baron $ */
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
* The program has a few sort of class definitions, which are the result of
* object oriented thinking, to be imlemented in plain C. I just haven't
* had the time to learn C++ or install the compiler. The design does however
* improve robustness, which allows the source to be used over and over again.
* if you use this code, please leave a little origin note.
*
*/
const char *version_str= "$VER: fd2inline $Revision$ $Date$";
/*
* These are general definitions including types for defining registers etc.
*/
#ifdef WDEBUG
# define DBP(a) printf2 a
void printf2( const char *fmt, ... )
{
vfprintf( stderr, fmt, (char *)(&fmt+1) );
}
#else
# define DBP(a)
#endif
#define REGS 16 /* d0=0,...,a7=15 */
typedef enum {
d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
} regs;
typedef unsigned char uchar, shortcard;
typedef unsigned long ulong;
typedef enum { false, nodef, real_error } Error;
/*
* just some support functions, no checking
*/
char *NewString( char **new, const char * old )
{
const char *high;
ulong len;
while ( *old && (' ' == *old || '\t' == *old) ) old++;
len= strlen( old );
for (high=old+len-1; high>=old && (' ' == *high || '\t' == *high); high-- );
high++;
len= high-old;
*new = (char *)malloc( 1+len );
if (*new) {
strncpy( *new, old, len );
(*new)[len]= '\0'; }
else {
fprintf( stderr, "no mem for string\n" ); }
return *new;
}
void illparams( const char *funcname )
{
fprintf( stderr, "%s: illegal Parameters\n", funcname );
}
const char * RegStr( regs reg )
{
const char *myregs[]= {
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal" };
if ( reg > illegal ) reg= illegal;
if ( reg < d0 ) reg= d0;
return myregs[reg];
}
/*
* StrNRBrk
*
* searches string in from position at downwards, as long as in does not
* contain any character in not.
*
*/
const char * StrNRBrk( const char * in, const char *not, const char * at )
{
const char *chcheck;
Error ready;
chcheck = ""; /* if at<in, the result will be NULL */
for (ready=false; ready==false && at>=in; ) {
for (chcheck=not; *chcheck && *chcheck != *at; chcheck++);
if (*chcheck) ready= real_error;
else at--;
}
DBP(( "{%c}", *chcheck ));
return *chcheck ? at : NULL;
}
/*
* binSearch
*
* A binary search routine, wich operates on an array like you would use
* for qsort. The prototype does not contain the (*) bug...
*
* returns the address of the (a?) fitting object, or NULL;
*
* the binary intersection is (low+high)/2, so the highest value will never
* be reached, but the lowest value will. In the while condition, the diff
* has to be called last in case we got an empty array.
*
*/
void *binSearch ( void ** array, size_t elements, const void *lookfor,
int cmpfunc(const void **, const void **))
{
size_t low, high, index;
int diff;
DBP(( "bs(%ld): ", (long)elements ));
diff= 1; /* this needs to be so in case we got an empty array... */
low=0, high= elements; /* our algorithm never reaches elements */
while( index= (high+low)/2, /* somewhere inbetween */
high!=low && (diff= cmpfunc((const void **)array+index,&lookfor)) ) {
if (0<diff) {
high= index; /* our value was too big, so grow downwards */
DBP(( "<" )); }
else {
low= index + 1; /* the low value will be reached */
DBP(( ">" )); }
DBP(( "%ld ", (long)index ));
}
DBP(( "->%ld\n", diff ? -1L : (long)index ));
return diff ? NULL : array[index]; /* bingo */
}
/*
* CLASS fdFile
*
* stores a file with a temporary buffer (static length, sorry), a line number,
* an offset (used for library offsets and an error field.
* When there's no error, line will contain line #lineno and offset will be
* the last offset set by the interpretation of the last line. If there's been
* no ##bias line, this field assumes a bias of 30, which is the standard bias.
* It is assumed offsets are always negative.
*/
#define fF_BUFSIZE 1024
#define fF_BUFFMT "%1024[~ß]"
/* all you need to know about an fdFile you parse */
typedef struct {
FILE * file; /* the file we're reading from */
char line[ fF_BUFSIZE ]; /* the current line */
ulong lineno; /* current line number */
long offset; /* current fd offset (-bias) */
Error error; /* is everything o.k. */
} fdFile;
fdFile * fF_ctor( const char *fname );
void fF_dtor( fdFile *obj );
void fF_SetError( fdFile *obj, Error error );
void fF_SetOffset( fdFile *obj, long at );
Error fF_readln( fdFile *obj );
Error fF_GetError( const fdFile *obj );
long fF_GetOffset( const fdFile *obj );
char * fF_FuncName( fdFile *obj ); /* return name or null */
fdFile * fF_ctor( const char *fname )
{
fdFile * result;
if (fname) {
result= (fdFile *) malloc( sizeof(fdFile) );
if (result) {
result->file= fopen( fname, "r" );
if (result->file) {
result->lineno= 0;
fF_SetOffset( result, -30);
fF_SetError( result, false );
result->line[0]= '\0';
}
} }
else {
result= NULL;
illparams( "fF_ctor" ); }
return result;
}
void fF_dtor( fdFile *obj )
{
fclose( obj->file );
free( obj );
}
void fF_SetError( fdFile *obj, Error error )
{
if (obj)
obj->error= error;
else
illparams( "fF_SetError" );
}
void fF_SetOffset( fdFile *obj, long at )
{
if (obj)
obj->offset= at;
else
illparams( "fFSetOffset" );
}
Error fF_readln( fdFile *obj )
{
char *low, *bpoint;
long glen, /* the length we read until now */
len; /* the length of the last segment */
if (obj) {
low= obj->line;
glen= 0;
do {
obj->lineno++;
if (!fgets( low, fF_BUFSIZE-1-glen, obj->file )) {
fF_SetError( obj, real_error );
obj->line[0]= '\0';
return real_error; }
if (low==strpbrk(low,"*#/")) {
DBP(( "in# %s\n", obj->line ));
return false; }
len= strlen( low );
bpoint= low+len-1;
if ('\n'==*bpoint) *bpoint='\0', bpoint--, len--;
if (';'==*bpoint || ')'==*bpoint ) {
DBP(( "\nin: %s\n", obj->line ));
return false; }
glen+= len;
low+= len;
if (glen >= fF_BUFSIZE-10) { /* somewhat pessimistic ? */
fF_SetError(obj, real_error);
fprintf( stderr, "line %lu too long.\n", obj->lineno );
return real_error;
}
DBP(( "+" ));
} while (!0);
}
illparams( "fF_readln" );
return real_error;
}
/*
* fF_FuncName
*
* checks if it can find a function-name and return it's address, or NULL
* if the current line does not semm to contain one. The return value will
* be a pointer into a malloced buffer, thus the caller will have to free().
*/
char * fF_FuncName( fdFile *obj )
{
const char *lower;
const char *upper;
char *buf;
long obraces; /* count of open braces */
Error ready; /* ready with searching */
if (!obj || real_error==fF_GetError(obj)) {
illparams( "fF_FuncName" );
return NULL;
}
if (obj->line==strpbrk(obj->line, "#*/")) {
fF_SetError( obj, nodef );
return NULL;
}
lower= NULL;
buf= NULL;
if (obj && false == fF_GetError(obj)) {
if ( upper=strrchr(obj->line, ')' )) {
DBP(( "end:%s:", upper ));
for(obraces= 1, ready= false; false== ready; upper=lower ) {
lower= StrNRBrk( obj->line, "()", --upper );
if (lower) {
switch (*lower) {
case ')': {
obraces++;
DBP(( " )%ld%s", obraces, lower ));
break; }
case '(': {
obraces--;
DBP(( " (%ld%s", obraces, lower ));
if (!obraces) ready= nodef;
break; }
default: {
fprintf( stderr, "faulty StrNRBrk\n" );
}
} }
else {
fprintf( stderr, "'(' or ')' expected in line %lu.\n", obj->lineno );
ready= real_error;
}
}
if (nodef==ready) { /* we found the matching '(' */
long newlen;
upper--;
while (upper>=obj->line && (' ' == *upper || '\t' == *upper) ) upper--;
lower= StrNRBrk( obj->line, " \t*)", upper );
if (!lower) lower=obj->line;
else lower++;
newlen= upper-lower+2;
buf= malloc( newlen );
if (buf) {
strncpy( buf, lower, --newlen );
buf[newlen]= '\0';
}
else fprintf( stderr, "no mem for fF_FuncName" );
}
}
}
else illparams( "fF_FuncName" );
return buf;
}
Error fF_GetError( const fdFile *obj )
{
if (obj) return obj->error;
illparams( "fF_GetError" );
return real_error;
}
long fF_GetOffset( const fdFile *obj )
{
if (obj) return obj->offset;
illparams( "fF_GetOffset" );
return -1;
}
/* ####################################################################### */
/* ####################################################################### */
/* ####################################################################### */
/*
* CLASS fdDef
*/
typedef struct {
char * name;
char * type;
long offset;
regs reg[REGS];
char * param[REGS];
char * proto[REGS];
} fdDef;
fdDef * fD_ctor( void );
void fD_dtor( fdDef *obj );
void fD_NewName( fdDef *obj, const char *newname );
void fD_NewParam( fdDef *obj, shortcard at, const char * newstr );
void fD_NewProto( fdDef *obj, shortcard at, const char * newstr );
void fD_NewReg( fdDef *obj, shortcard at, regs reg );
void fD_NewType( fdDef *obj, const char * newstr );
void fD_SetOffset( fdDef *obj, long off );
Error fD_parsefd( fdDef *obj, fdFile * infile );
Error fD_parsepr( fdDef *obj, fdFile * infile );
const char * fD_GetName( const fdDef *obj );
long fD_GetOffset( const fdDef *obj );
const char * fD_GetParam( const fdDef *obj, shortcard at );
regs fD_GetReg( const fdDef *obj, shortcard at );
const char * fD_GetRegStr( const fdDef *obj, shortcard at );
const char * fD_GetType( const fdDef *obj );
shortcard fD_ParamNum( const fdDef *obj );
shortcard fD_ProtoNum( const fdDef *obj );
shortcard fD_RegNum( const fdDef *obj );
int fD_cmpName( const fdDef **big, const fdDef **small );
void fD_write( const fdDef *obj );
char * fD_nostring = "";
fdDef * fD_ctor( void )
{
fdDef * result;
regs count;
result= (fdDef *) malloc(sizeof(fdDef));
if (result) {
result->name= fD_nostring;
result->type= fD_nostring;
for ( count=d0; count<illegal; count++ ) {
result->reg[count]= illegal;
result->param[count]= fD_nostring; /* if (!strlen) dont't free() */
result->proto[count]= fD_nostring;
} }
return result;
}
/* free all resources and make the object as illegal as possible */
void fD_dtor( fdDef * obj )
{
regs count;
if (obj) {
if (!obj->name) fprintf( stderr, "fD_dtor: null name" );
else if (obj->name != fD_nostring) free( obj->name );
if (!obj->type) fprintf( stderr, "fD_dtor: null type" );
else if (obj->type != fD_nostring) free( obj->type );
obj->name= obj->type= NULL;
for (count= d0; count<illegal; count++) {
obj->reg[count]= illegal;
if (!obj->param[count]) fprintf( stderr, "fD_dtor: null param" );
else if (obj->param[count] != fD_nostring) free(obj->param[count]);
if (!obj->proto[count]) fprintf( stderr, "fD_dtor: null proto" );
else if (obj->proto[count] != fD_nostring) free(obj->proto[count]);
obj->param[count]= obj->proto[count]= NULL; }
free(obj);
}
else fprintf( stderr, "dfDef_dtor(NULL)\n" );
}
void fD_NewName( fdDef *obj, const char *newname )
{
if (obj && newname) {
if (obj->name && fD_nostring != obj->name ) free( obj->name );
if (!NewString( &obj->name, newname )) obj->name= fD_nostring; }
else illparams( "fD_NewName" );
}
void fD_NewParam( fdDef *obj, shortcard at, const char * newstr )
{
char * pa;
if (newstr && obj && at>=d0 && at<illegal) {
pa= obj->param[at];
if (pa && fD_nostring != pa) free( pa );
if (NewString( &pa, newstr)) {
obj->param[at]= pa; }
else {
obj->param[at]= fD_nostring;
} }
else illparams( "fD_NewParam" );
}
void fD_NewProto( fdDef *obj, shortcard at, const char * newstr )
{
char * pr;
if (newstr && obj && at>=d0 && at<illegal) {
pr= obj->proto[at];
if (pr && fD_nostring != pr) free( pr );
if (NewString( &pr, newstr)) {
obj->proto[at]= pr; }
else {
obj->proto[at]= fD_nostring;
} }
else illparams( "fD_NewProto" );
}
void fD_NewReg( fdDef *obj, shortcard at, regs reg )
{
if (obj && at>=d0 && at<illegal && reg>=d0 && reg<=illegal) {
obj->reg[at] = reg; }
else illparams( "fD_NewReg" );
}
void fD_NewType( fdDef *obj, const char *newtype )
{
if (obj && newtype) {
if (obj->type && fD_nostring != obj->type ) free( obj->type );
if (!NewString( &obj->type, newtype )) obj->type= fD_nostring; }
else illparams( "fD_NewType" );
}
void fD_SetOffset( fdDef *obj, long off )
{
if (obj) {
obj->offset=off; }
else {
illparams( "fD_SetOffset" );
}
}
/* fD_parsefd
*
* parse the current line. Needs to copy input, in order to insert \0's
* RETURN
* fF_GetError(infile):
* false = read a definition.
* nodef = not a definition on line (so try again)
* error = real error
*/
Error fD_parsefd( fdDef * obj, fdFile * infile )
{
enum parse_info { name, params, regs, ready } parsing;
char *buf, *bpoint, *bnext;
ulong index;
if (obj && infile && (false == fF_GetError(infile))) {
parsing= name;
if (!NewString( &buf, infile->line )) {
fprintf( stderr, "no mem for line %lu\n", infile->lineno );
fF_SetError( infile, real_error );
}
bpoint= buf; /* so -Wall keeps quiet */
/* printf("copied %lu: %s", infile->lineno, buf ); */
/* try to parse the line until there's an error or we are done */
while (ready != parsing && false == fF_GetError(infile)) {
switch (parsing) {
case name: {
switch (buf[0]) {
case '#': {
if (!strncmp("##bias", buf, 6)) {
if (1!=sscanf( buf+6, "%ld", &infile->offset )) {
fprintf( stderr, "illegal ##bias in line %lu: %s\n",
infile->lineno, infile->line );
fF_SetError( infile, real_error );
break; } /* avoid nodef */
else {
if (fF_GetOffset(infile) > 0)
fF_SetOffset(infile, -fF_GetOffset(infile));
/* printf("set offset to %ld\n", fFGetOffset(infile); */
}
} } /* drop through for error */
case '*': { /* comment */
fF_SetError( infile, nodef ); /* try again somewhere else */
break; }
default: { /* assume a regular line here */
parsing= name;
/* switch (parsing) */
for (index=0; buf[index] && buf[index]!='('; index++ );
if (!buf[index]) { /* oops, no fd ? */
fprintf( stderr, "not an fd, line %lu: %s\n",
infile->lineno, buf /* infile->line */ );
fF_SetError(infile, nodef); } /* maybe next time */
else {
buf[index]=0;
fD_NewName( obj, buf );
fD_SetOffset( obj, fF_GetOffset(infile) );
bpoint= buf+index+1;
parsing= params; /* continue the loop */
}
} }
break; }
case params: {
char *bptmp; /* needed for fD_NewParam */
/* look for parameters now */
for ( bnext= bpoint
; *bnext && *bnext!=',' && *bnext!=')'
; bnext++ );
if (*bnext) {
bptmp=bpoint;
if (')'==*bnext) {
if ('('!=bnext[1]) {
fprintf( stderr, "registers expected in line %lu: %s\n",
infile->lineno, infile->line );
fF_SetError(infile, nodef); }
else {
parsing= regs;
bpoint= bnext+2;
}
}
else bpoint= bnext+1;
/* terminate string and advance to next item */
*bnext= '\0';
fD_NewParam( obj, fD_ParamNum(obj), bptmp );
}
else {
fF_SetError(infile, nodef);
fprintf( stderr, "param expected in line %lu: %s\n",
infile->lineno, infile->line );
}
break; } /* switch parsing */
case regs: {
/* look for parameters now */
for ( bnext= bpoint
; *bnext && *bnext!='/' && *bnext!=',' && *bnext!=')'
; bnext++ );
if (*bnext) {
if (')'==*bnext) { /* wow, we've finished */
fF_SetOffset( infile, fF_GetOffset(infile)-6 );
parsing= ready;
}
*bnext= '\0';
if ( ('d'==bpoint[0] || 'a'==bpoint[0])
&& '0'<=bpoint[1] && '8'>=bpoint[1] && bnext == bpoint+2)
fD_NewReg( obj, fD_RegNum(obj),
bpoint[1]-'0'+(bpoint[0]=='a'?8:0) );
else if (bnext!=bpoint) { /* it is when our function is void */
fprintf( stderr, "illegal register %s in line %ld\n",
bpoint, infile->lineno );
fF_SetError(infile, nodef); }
bpoint= bnext+1;
}
else {
fF_SetError(infile, nodef);
fprintf( stderr, "reg expected in line %lu\n", infile->lineno );
}
break; } /* switch parsing */
case ready: {
fprintf( stderr, "internal error, use another compiler.\n" );
break;
}
} }
free( buf );
return fF_GetError(infile); }
else {
illparams( "fD_parsefd" );
return real_error;
}
}
Error fD_parsepr( fdDef *obj, fdFile * infile )
{
char *buf; /* a copy of infile->line */
char *bpoint, /* cursor in buf */
*bnext, /* looking for the end */
*lowarg; /* beginning of this argument */
long obraces; /* count of open braces */
regs count, /* count parameter number */
args; /* the number of arguments for this function */
if (!(obj && infile && false==fF_GetError(infile))) {
illparams( "fD_parsepr" );
fF_SetError( infile, real_error );
return real_error;
}
if (!NewString( &buf, infile->line )) {
fprintf( stderr, "no mem for fD_parsepr\n" );
fF_SetError( infile, real_error );
return real_error;
}
fF_SetError( infile, false );
if (bpoint= strstr( buf, fD_GetName(obj) ) ) {
while (--bpoint>=buf && (' '== *bpoint || '\t'== *bpoint)) bpoint--;
*++bpoint= '\0';
fD_NewType( obj, buf );
while(bpoint && '('!=*bpoint++); /* one beyond '(' */
lowarg= bpoint;
obraces= 0;
for (count=0, args=fD_RegNum(obj); count<args; bpoint= bnext+1 ) {
while(*bpoint && ' '==*bpoint) bpoint++; /* ignore spaces */
bnext= strpbrk( bpoint, "()," );
if (bnext) {
switch (*bnext) {
case '(': {
obraces++;
DBP(( "< (%ld%s >", obraces, bnext ));
break; }
case ')': {
if (obraces) {
DBP(( "< )%ld%s >", obraces, bnext ));
obraces--; }
else {
*bnext= '\0';
DBP(( "< )0> [LAST PROTO=%s]", lowarg ));
fD_NewProto( obj, count, lowarg );
lowarg= bnext+1;
if (count!=args-1) {
/*
fprintf( stderr, "%s needs %u arguments and got %u.\n",
fD_GetName(obj), args, count+1 );
*/
fF_SetError( infile, nodef ); }
count++; }
break; }
case ',': {
if (!obraces) {
*bnext= '\0';
DBP(( " [PROTO=%s] ", lowarg ));
fD_NewProto( obj, count, lowarg );
lowarg= bnext+1;
count++; }
break; }
default: {
fprintf( stderr, "faulty strpbrk in line %lu.\n", infile->lineno );
}
} }
else {
/*
fprintf( stderr, "faulty argument %u in line %lu.\n",
count+1, infile->lineno );
*/
count=args; /* this will effectively quit the for loop */
fF_SetError( infile, nodef );
}
}
if (fD_ProtoNum(obj) != fD_RegNum(obj)) {
fF_SetError( infile, nodef );
}
}
else {
fprintf( stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno );
fprintf( stderr, "function , definition %s.\n",
/* fD_GetName(obj),*/ infile->line );
fF_SetError( infile, nodef );
}
free( buf );
return fF_GetError(infile);
}
const char * fD_GetName( const fdDef *obj )
{
if (obj && obj->name) {
return obj->name; }
else {
illparams( "fD_GetName" );
return fD_nostring;
}
}
long fD_GetOffset( const fdDef *obj )
{
if (obj) {
return obj->offset; }
else {
illparams( "fD_GetOffset" );
return 0;
}
}
const char * fD_GetProto( const fdDef *obj, shortcard at )
{
if (obj && at>=d0 && at<illegal && obj->proto[at]) {
return obj->proto[at]; }
else {
illparams( "fD_GetProto" );
return fD_nostring;
}
}
const char * fD_GetParam( const fdDef *obj, shortcard at )
{
if (obj && at>=d0 && at<illegal && obj->param[at]) {
return obj->param[at]; }
else {
illparams( "fD_GetParam" );
return fD_nostring;
}
}
regs fD_GetReg( const fdDef *obj, shortcard at )
{
if (obj && at>=d0 && at<illegal) {
return obj->reg[at]; }
else {
illparams( "fD_GetReg" );
return illegal;
}
}
const char *fD_GetRegStr( const fdDef *obj, shortcard at )
{
if (obj && at>=d0 && at<illegal) {
return RegStr( obj->reg[at] ); }
else {
illparams( "fD_GetReg" );
return RegStr( illegal );
}
}
const char * fD_GetType( const fdDef *obj )
{
if (obj && obj->type) {
return obj->type; }
else {
illparams( "fD_GetType" );
return fD_nostring;
}
}
/* get first free param or illegal */
shortcard fD_ParamNum( const fdDef *obj )
{
shortcard count;
if (obj) {
for ( count= d0; count<illegal && fD_nostring!=obj->param[count]; count++ );
return count; }
else {
illparams( "fD_ParamNum" );
return illegal;
}
}
shortcard fD_ProtoNum( const fdDef *obj )
{
shortcard count;
if (obj) {
for ( count= d0; count<illegal && fD_nostring!=obj->proto[count]; count++ );
return count; }
else {
illparams( "fD_ProtoNum" );
return illegal;
}
}
/* get first free *reg or illegal */
shortcard fD_RegNum( const fdDef *obj )
{
shortcard count;
if (obj) {
for ( count= d0; count<illegal && illegal!=obj->reg[count]; count++ );
return count; }
else {
illparams( "fD_RegNum" );
return illegal;
}
}
int fD_cmpName( const fdDef **big, const fdDef **small ) /* for qsort */
{
int res;
res = strcmp( fD_GetName( *big ), fD_GetName( *small ) );
return res;
}
void fD_write( const fdDef * obj )
{
shortcard count, numregs;
const char *chtmp;
DBP(("func %s\n", fD_GetName(obj) ));
numregs= fD_RegNum(obj);
if (fD_nostring == fD_GetType(obj)) {
fprintf( stderr, "%s has no prototype.\n", fD_GetName(obj) );
return; }
if (fD_ProtoNum(obj) != numregs) {
fprintf( stderr, "%s gets %ld fd args and %ld proto%s.\n",
fD_GetName(obj), numregs, fD_ProtoNum(obj),
fD_ProtoNum(obj) != 1 ? "s" : "" );
return;
}
printf( "__inline static void %s( BASE_PAR_DECL", fD_GetName(obj) );
if (0<numregs) {
for( count=d0; count<numregs-1; count++) {
printf( " %s ", fD_GetProto(obj,count) );
printf( " %s,", fD_GetParam(obj,count) ); }
printf( " %s ", fD_GetProto(obj,count) );
printf( " %s", fD_GetParam(obj,count) ); }
else
putchar( '0' );
puts( " )\n{\n\tBASE_EXT_DECL\n\tregister res __asm(\"d0\");" );
puts( "\tregister void *a6 __asm(\"a6\");" );
for( count=d0; count<numregs; count++) {
chtmp= fD_GetRegStr(obj,count);
printf( "\tregister %s %s __asm(\"%s\");\n",
fD_GetProto(obj,count), chtmp, chtmp ); }
puts( "" );
puts( "\ta6 = BASE_NAME;" );
for( count=d0; count<numregs; count++)
printf( "\t%s = %s;\n", fD_GetRegStr(obj,count), fD_GetParam(obj,count) );
puts( "\t__asm volatile (\"" );
printf( "\tjsr a6@@(-0x%lx)\"\n", -fD_GetOffset(obj) );
puts( "\t: \"=r\" (res)" );
printf( "\t: \"r\" (a6)" );
for( count=d0; count<numregs; count++)
printf( " \"r\" (%s)", fD_GetRegStr(obj,count) );
printf( "\n\t: \"d0\", \"d1\", \"a0\", \"a1\"" );
for( count=d0; count<numregs; count++) {
switch (fD_GetReg(obj,count)) {
case d0:
case d1:
case a0:
case a1: break;
default: {
printf( ", \"%s\"", fD_GetRegStr(obj,count) );
break;
}
} }
printf( " );\n\treturn res;\n}\n" );
}
#define FDS 1000
void main ( int argc, char **argv )
{
fdDef **mydef;
fdDef *tmpdef= NULL, /* a dummy to contain the name to look for */
*founddef; /* the fdDef for which we found a prototype */
fdFile *myfile;
char *tmpstr;
long count, fds;
Error lerror = false;
if (3!=argc) {
fprintf( stderr, "usage: %s fdfilename protofilename\n", argv[0] );
exit(20);
}
mydef= malloc( FDS*sizeof(fdDef *) );
if (mydef) {
for( count=0; count<FDS; count++) mydef[count]= NULL;
myfile= fF_ctor( argv[1] );
if (myfile) {
lerror= false;
for (count= 0; count<FDS && false==lerror; count++ ) {
mydef[count]= fD_ctor();
do {
if (false==(lerror=fF_readln(myfile))) {
fF_SetError(myfile, false);
lerror=fD_parsefd(mydef[count], myfile);
}
} while (nodef==lerror);
}
if (count<FDS) {
count--;
fD_dtor( mydef[count] );
mydef[count]= NULL;
}
fds= count;
/* the gnu stdlib.h seems to have a bug for qsort: int (*)(etc.) */
qsort( mydef, count, sizeof(fdDef *), (void *)fD_cmpName );
fF_dtor( myfile );
myfile= fF_ctor( argv[2] );
if (myfile) {
if (!tmpdef) tmpdef= fD_ctor();
for (lerror= false; false==lerror; ) {
do {
if (false==(lerror=fF_readln(myfile))) {
fF_SetError( myfile, false ); /* continue even on errors */
tmpstr= fF_FuncName( myfile );
if (tmpstr) {
fD_NewName( tmpdef, tmpstr );
founddef= binSearch( (void **)mydef, fds, tmpdef, (void *)fD_cmpName );
if (founddef) {
DBP(("found (%s).\n", fD_GetName( founddef ) ));
fF_SetError(myfile, false);
lerror= fD_parsepr(founddef, myfile);
}
else fprintf( stderr, "did not find <%s> in line %lu.\n",
tmpstr, myfile->lineno );
free( tmpstr );
}
else lerror= nodef;
}
} while (nodef==lerror);
}
fD_dtor(tmpdef);
tmpdef= NULL;
}
}
else fprintf( stderr, "Couldn't open file.\n" );
for (count=0; count<FDS && mydef[count]; count++) {
/* printf("outputting %ld...\n", count ); */
fD_write( mydef[count] );
fD_dtor( mydef[count] );
mydef[count]= NULL; }
fF_dtor( myfile );
myfile= NULL;
switch (lerror) {
case false: exit(0);
case nodef: exit(20);
case real_error: exit(20);
default: exit(30);
} }
else {
fprintf( stderr, "No mem for FDs\n" );
exit(20);
}
}
@
1.1
log
@Initial revision
@
text
@d5 2
a6 1
* for gcc. Works as a filter.
d12 1
a12 1
/* $Id$ */
d29 3
d36 13
d68 9
a76 1
*new = (char *)malloc( 1+strlen(old) );
d78 2
a79 1
strcpy( *new, old ); }
d91 74
d192 7
a198 4
void fF_dtor( fdFile *obj );
void fF_SetOffset( fdFile *obj, long at );
void fF_SetError( fdFile *obj, Error error );
Error fF_readln( fdFile *obj );
d213 1
a213 1
result->offset= -30;
d234 1
a234 1
void fF_SetOffset( fdFile *obj, long at )
d237 1
a237 1
obj->offset= at;
d239 1
a239 1
illparams( "fFSetOffset" );
d244 1
a244 1
void fF_SetError( fdFile *obj, Error error )
d247 1
a247 1
obj->error= error;
d249 1
a249 1
illparams( "fFSetError" );
d256 3
d261 27
a287 6
obj->lineno++;
if (!fgets( obj->line, fF_BUFSIZE-1, obj->file )) {
fF_SetError( obj, real_error);
obj->line[0]=0;
return real_error; }
return false; }
d294 91
d386 3
d397 1
d401 1
d405 20
a424 13
void fD_dtor( fdDef *obj );
void fD_NewName( fdDef *obj, const char *newname );
void fD_SetOffset( fdDef *obj, long off );
void fD_NewParam( fdDef *obj, shortcard at, const char * newstr );
void fD_NewReg( fdDef *obj, shortcard at, regs reg );
const char * fD_GetName( fdDef *obj );
long fD_GetOffset( fdDef *obj );
const char * fD_GetParam( fdDef *obj, shortcard at );
regs fD_GetReg( fdDef *obj, shortcard at );
Error fD_sparse( fdDef *obj, fdFile * infile );
void fD_write( fdDef *obj );
shortcard fD_ParamNum( fdDef *obj );
shortcard fD_RegNum( fdDef *obj );
d437 2
a438 1
result->name=0;
d442 1
d449 1
d455 5
d462 7
a468 2
if (obj->param[count] != fD_nostring) free(obj->param[count]);
} }
d477 1
a483 11
void fD_SetOffset( fdDef *obj, long off )
{
if (obj) {
obj->offset=off; }
else {
illparams( "fD_SetOffset" );
}
}
a486 1
size_t len;
d501 1
a501 1
void fD_NewReg( fdDef *obj, shortcard at, regs reg )
d503 1
a503 4
if (obj && at>=d0 && at<illegal && reg>=d0 && reg<=illegal) {
obj->reg[at] = reg; }
else illparams( "fD_NewReg" );
}
d505 9
a513 10
long fD_GetOffset( fdDef *obj )
{
if (obj) {
return obj->offset; }
else {
illparams( "fD_GetOffset" );
return 0;
}
d518 1
a518 1
const char * fD_GetName( fdDef *obj )
d520 3
a522 15
if (obj && obj->name) {
return obj->name; }
else {
illparams( "fD_GetParam" );
return fD_nostring;
}
}
const char * fD_GetParam( fdDef *obj, shortcard at )
{
if (obj && at>=d0 && at<illegal && obj->param[at]) {
return obj->param[at]; }
else illparams( "fD_GetParam" );
d527 1
a527 1
regs fD_GetReg( fdDef *obj, shortcard at )
d529 4
a532 3
if (obj && at>=d0 && at<illegal) {
return obj->reg[at]; }
else illparams( "fD_GetReg" );
d537 1
a537 2
/* get first free ->param or illegal */
shortcard fD_ParamNum( fdDef *obj )
a538 2
shortcard count;
d540 1
a540 2
for ( count= d0; count<illegal && fD_nostring!=obj->param[count]; count++ );
return count; }
d542 1
a542 18
illparams( "fD_ParamNum" );
return illegal;
}
}
/* get first free ->reg or illegal */
shortcard fD_RegNum( fdDef *obj )
{
shortcard count;
if (obj) {
for ( count= d0; count<illegal && illegal!=obj->reg[count]; count++ );
return count; }
else {
illparams( "fD_RegNum" );
return illegal;
d548 1
a548 1
/* fD_sparse
d552 1
a552 1
* fdFile->error:
d557 1
a557 1
Error fD_sparse( fdDef * obj, fdFile * infile )
a558 1
regs count;
d561 1
a561 1
ulong index, tmpindex;
d563 1
a563 1
if (obj && infile && (false == infile->error)) {
d567 1
a567 1
infile->error= real_error;
d569 1
d573 1
a573 1
while (ready != parsing && false == infile->error) {
d583 1
a583 1
infile->error= real_error;
d586 3
a588 2
if (infile->offset > 0) infile->offset= -infile->offset;
/* printf("set offset to %ld\n", infile->offset ); */
d590 3
a592 3
} } /* drop through for error */
case '*': { /* comment */
infile->error = nodef; /* try again somewhere else */
d600 2
a601 2
infile->lineno, infile->line );
infile->error= nodef; } /* maybe next time */
d605 1
a605 1
fD_SetOffset( obj, infile->offset );
d623 1
a623 1
infile->error= nodef; }
d635 1
a635 1
infile->error= nodef;
d647 1
a647 1
infile->offset -= 6;
d658 1
a658 1
infile->error= nodef; }
d662 1
a662 1
infile->error= nodef;
d665 4
a668 2
break; /* switch parsing */
d672 1
a672 1
return infile->error; }
d674 26
a699 1
illparams( "fD_sparse" );
d702 169
d875 14
d890 2
a891 1
void fD_write( fdDef * obj )
d894 7
a900 3
printf("%ld %s ( ", fD_GetOffset(obj), fD_GetName(obj) );
for( count=d0; count<illegal && illegal!=fD_GetReg(obj,count); count++) {
printf( "%s in %d, ", fD_GetParam(obj,count), (int)fD_GetReg(obj,count) );
d902 67
a968 1
printf( ")\n" );
d980 2
d983 1
d985 1
a985 1
Error lerror;
d987 2
a988 2
if (2!=argc) {
fprintf( stderr, "usage: %s fdfilename\n", argv[0] );
d1002 2
a1003 2
myfile->error= false;
lerror=fD_sparse(mydef[count], myfile);
d1012 31
d1044 1
d1048 2
a1049 1
fD_dtor( mydef[count] ); }
d1051 1
@